<?php

namespace App\Storage;

use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\Component\Singleton;
use EasySwoole\Component\TableManager;
use Swoole\Table;

/**
 *  在线网页用户
 *
 * @Author LYC 17750800820@163.com
 * @DateTime 2020-04-22 14:33:07
 *
 */
class OnlineUser
{
    use Singleton;
    protected $table;  // 储存终端信息的Table

    // const INDEX_TYPE_FD_ID = 1;

    /**
     * OnlineUser constructor.
     */
    public function __construct()
    {
        TableManager::getInstance()->add('onlineUsers', [
            'name'=>['type'=>Table::TYPE_STRING, 'size'=>64],
            'token' => ['type' => Table::TYPE_STRING, 'size' => 128],
            'last_heartbeat' => ['type' => Table::TYPE_INT, 'size' => 16]
        ]);

        $this->table = TableManager::getInstance()->get('onlineUsers');
    }

    /**
     * 设置一个网页用户
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 14:51:30
     * @param integer $fd
     * @param string $name
     * @return void
     */
    public function set($fd, $name, $token)
    {
        return $this->table->set($fd, [
            'name' => $name,
            'last_heartbeat' => time()
        ]);
    }

    /**
     * 获取一个网页用户
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 15:01:38
     * @param integer $fd
     * @return void
     */
    public function get($fd)
    {
        $info = $this->table->get($fd);
        return is_array($info) ? $info : null;
    }

    /**
     * 更新个网页用户
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 15:02:27
     * @param integer $fd
     * @param string $data
     * @return void
     */
    public function update($fd, $data)
    {
        $info = $this->get($fd);
        if (!empty($info)) {
            foreach ($data as $key => $val) {
                $info[$key] = $val;
            }
            $this->table->set($fd, $info);
        }
    }

    /**
     * 删除一个网页用户
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 15:11:39
     * @param integer $fd
     * @return void
     */
    public function delete($fd)
    {
        if ($this->table->exist($fd)) {
            $this->table->del($fd);
        }
    }

    /**
     * 心跳检查
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 15:13:05
     * @param integer $ttl
     * @return void
     */
    public function heartbeatCheck($ttl = 60)
    {
        // 千万不要用数组方式读取Table , 可以foreach出来 https://www.easyswoole.com/Cn/Swoole/ProcessCommunication/table.html
        foreach ($this->table as $item) {
            $time = $item['last_heartbeat'];
            // 上次心跳时间+心跳周期时间 < 当前时间, 判断为掉线, 删除这条终端信息
            if (($time + $ttl) < time()) {
                $this->delete($item['fd']);
                // 关闭该连接
                $server = ServerManager::getInstance()->getSwooleServer();
                $server->close($fd);          
            }
        }
    }

    /**
     *  更新上次心跳时间
     *
     * @Author LYC 17750800820@163.com
     * @DateTime 2020-04-22 15:18:31
     * @param integer $fd
     * @return void
     */
    public function updateHeartbeat($fd)
    {
        $this->update($fd, [
            'last_heartbeat' => time()
        ]);
    }

    /**
     * 直接获取当前的表
     * @return Table|null
     */
    public function table()
    {
        return $this->table;
    }
}
